LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;

--input comes from the PC and PC+4 from the adder
entity regex is
port ( 
    CLK							     :		 in	std_logic;
    nReset         :   in std_logic;
    bubble         :   in std_logic;
    exen           :   in std_logic;
    exPC4          :   in std_logic_vector (31 downto 0);   
    exALU_out      :   in std_logic_vector(31 downto 0);
    exREG_RDAT2    :   in std_logic_vector(31 downto 0);
    exRd     :   in std_logic_vector(4 downto 0);
    exWBctrl       :   in std_logic_vector(3 downto 0);
    exMEMctrl      :   in std_logic_vector(2 downto 0);
    exImmExtend    :   in std_logic_vector(31 downto 0);
    exhalt         :   in std_logic;
    
    memALU_out     :   out std_logic_vector(31 downto 0);
    memREG_RDAT2   :   out std_logic_vector(31 downto 0);
    memRd    :   out std_logic_vector(4 downto 0);
    memWBctrl      :   out std_logic_vector(3 downto 0);
    MEMctrl        :   out std_logic_vector(2 downto 0);
    memImmExtend   :   out std_logic_vector(31 downto 0);
    memhalt        :   out std_logic;
    memPC4          :   out std_logic_vector (31 downto 0)
  );
end regex;

architecture arch of regex is
  signal q0, n0  : std_logic_vector (31 downto 0);  --
  signal q1, n1  : std_logic_vector (31 downto 0);  --
  signal q2, n2  : std_logic_vector (4 downto 0);  --
  signal q3, n3  : std_logic_vector (3 downto 0);
  signal q4, n4  : std_logic_vector (2 downto 0);
  signal q5, n5  : std_logic;
  signal q6, n6  : std_logic_vector (31 downto 0);
  signal q7, n7  : std_logic_vector (31 downto 0);
  
begin
  
  proc : process(CLK,nReset, bubble)
  begin
    if (nReset = '0')  then
      q0 <= x"00000000";
      q1 <= x"00000000";
      q2 <= "00000";
      q3 <= (others => '0');
      q4 <= (others => '0');
      q5 <= '0';
      q6 <= (others => '0');
      q7 <= (others => '0');

    elsif rising_edge(CLK) then
      if (bubble = '1') then
        q0 <= (others => '0');
        q1 <= (others => '0');
        q2 <= (others => '0');
        q3 <= (others => '0');
        q4 <= (others => '0');
        q5 <= '0';
        q6 <= (others => '0');
        q7 <= (others => '0');      
      else
        q0 <= n0;
        q1 <= n1;
        q2 <= n2;
        q3 <= n3;
        q4 <= n4;
        q5 <= n5;
        q6 <= n6;
        q7 <= n7;
      end if;
      
    end if;
  end process proc;

  n0 <= exALU_out when exen = '1' else
        q0 when exen = '0' else
        x"00000000";
  n1 <= exREG_RDAT2 when exen = '1' else
        q1 when exen = '0' else
        x"00000000";
  n2 <= exRd when exen = '1' else
        q2 when exen = '0' else
        "00000";
  n3 <= exWBctrl when exen = '1' else
        q3 when exen = '0' else
        (others => '0');
  n4 <= exMEMctrl when exen = '1' else
        q4 when exen = '0' else
        (others => '0');
  n5 <= exhalt when exen = '1' else
        q5 when exen = '0' else
        '0';    
        
  n6 <= exImmExtend when exen = '1' else
        q6 when exen = '0' else
        (others => '0');  

  n7 <= exPC4 when exen = '1' else
        q7 when exen = '0' else
        (others => '0');  

        
            
  memALU_out            <= q0;
  memREG_RDAT2      <= q1;
  memRd      <= q2;
  memWBctrl        <= q3;
  MEMctrl            <= q4;
  memhalt         <= q5;
  memImmExtend    <= q6;
  memPC4          <= q7;
  
     
end arch;